package com.atguigu.day2;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * CopyOnWrite容器即写时复制的容器。往一个容器添加元素的时候，不直接往当前容器Object[]添加，
 *         而是先将当前容器Object[]进行Copy，复制出一个新的容器Object[] newElements，
 *         然后向新的容器Object[] newElements里添加元素。
 *         添加元素后，再将原容器的引用指向新的容器setArray(newElements)。
 *         这样做的好处是可以对CopyOnWrite容器进行并发的读，而不需要加锁，因为当前容器不会添加任何元素。
 *         所以CopyOnWrite容器也是一种读写分离的思想，读和写不同的容器。
 */

public class NotSafeDemo {
    public static void main(String[] args) {
        //new ArrayList<>();线程不安全，会报java.util.ConcurrentModificationException 并发修改异常
        //new Vector<>();线程安全，可以代替ArrayList
        //使用集合工具类使得线程安全Collections.synchronizedXxxx();例：Collections.synchronizedList(new ArrayList<>())
        //最终版本:写时复制，读写分离
        /*List<Integer> list = new CopyOnWriteArrayList<>();
        Random random = new Random();
        for (int j = 0; j < 100; j++) {
            new Thread(() -> {
                list.add(random.nextInt());
                System.out.println(list);
            }, "A").start();
        }*/


        //线程安全版本的set
        /*Set<Integer> set = new CopyOnWriteArraySet<>();
        Random random = new Random();
        for (int i = 0; i < 500; i++) {
            new Thread(() -> {
                set.add(random.nextInt());
                System.out.println(set);
            },"B").start();
        }*/

        //线程安全版本的Map
        Map<Integer,Integer> map = new ConcurrentHashMap<>();
        Random random = new Random();
        for (int i = 0; i < 100; i++) {
            new Thread(() ->{
                map.put(random.nextInt(),random.nextInt());
                System.out.println(map);
            }).start();
        }
    }
}
